import type { RouteRecordRaw } from 'vue-router';
import { UserService } from '@/apis/user';
import { warningMessage } from '@/helpers/antd/message';
import { errorNotification } from '@/helpers/antd/notification';
import Layout from '@/pages/layouts/index.vue';
import asyncPages from '@/routers/async-page';

import path from 'path-browserify';
import { defineStore } from 'pinia';

function buildRoutes(menus: MenuApiResp.Menu[], basePath = ''): RouteRecordRaw[] {
  return menus.map(menu => {
    const route: RouteRecordRaw = {
      name: menu.id,
      path: menu.path,
      meta: {
        title: menu.name,
        icon: menu.icon,
        keepAlive: menu.keepAlive,
        affix: menu.affix,
      },
      children: [],
    };
    if (menu.children?.length) {
      route.component = Layout;
      route.children = buildRoutes(menu.children, path.join(basePath, menu.path));
    } else {
      const url = menu.path.startsWith('/') ? menu.path : path.join(basePath, menu.path);
      const asyncPage = asyncPages[url];
      if (!asyncPage) {
        warningMessage(`页面 ${url} 不存在，请检查！`);
      }
      route.component = asyncPage;
    }
    return route;
  });
}

export const useAsyncRouteStore = defineStore('async-routes', () => {
  const isFetched = ref<boolean>(false);
  const menus = ref<MenuApiResp.Menu[]>([]);
  const cachedRoutes = ref<string[]>([]);
  const routeRemovers = ref<Array<() => void>>([]);

  const routes = computed(() => buildRoutes(menus.value));

  function addCachedRoute(route: string) {
    if (!cachedRoutes.value.includes(route)) {
      cachedRoutes.value.push(route);
    }
  }

  function removeCacheRoute(route: string) {
    const index = cachedRoutes.value.indexOf(route);
    if (index > -1) {
      cachedRoutes.value.splice(index, 1);
    }
  }

  function addRouteRemover(remover: () => void) {
    routeRemovers.value.push(remover);
  }

  function removeAllRoute() {
    routeRemovers.value.forEach(remover => remover());
    routeRemovers.value = [];
  }

  function clearMenus() {
    isFetched.value = false;
    menus.value = [];
    cachedRoutes.value = [];
  }

  async function fetchUserMenuListAction(): Promise<boolean> {
    try {
      const { data } = await UserService.fetchUserMenuList();
      menus.value = data;
      isFetched.value = true;
      return true;
    } catch {
      return false;
    }
  }

  return {
    isFetched,
    menus,
    cachedRoutes,
    routes,
    addCachedRoute,
    removeCacheRoute,
    addRouteRemover,
    removeAllRoute,
    clearMenus,
    fetchUserMenuListAction,
  };
});
